﻿namespace MicroCloud.Entity.BatchConfiguration
{
    /// <summary>
    /// 给实体属性添加Comment配置
    /// 生成数据库时将属性[Description]/[DisplayName]/[Display]特性的值添加到表字段的描述信息中
    /// </summary>
    public class PropertyCommentConfiguration : IEntityBatchConfiguration
    {
        /// <summary>
        /// 配置指定的<see cref="IMutableEntityType"/>
        /// </summary>
        /// <param name="modelBuilder">模型构建器</param>
        /// <param name="mutableEntityType">实体的 <see cref="IMutableEntityType"/> 类型</param>
        /// <param name="database">数据库相关信息和操作的访问 <see cref="DatabaseFacade"/> 类型</param>
        /// <param name="dbContextOptions">数据上下文配置 <see cref="DbContextOption"/> 类型</param>
        /// <param name="dbContextType">数据上下文类型</param>
        public void Configure(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType, DatabaseFacade database, DbContextOption dbContextOptions, Type dbContextType)
        {
            // 添加表说明
            var entityDescription = mutableEntityType.ClrType.GetDescription();
            if (!entityDescription.IsMissing())
            {
                //modelBuilder.Entity(mutableEntityType.ClrType).HasComment(entityDescription); //7.0已过时
                modelBuilder.Entity(mutableEntityType.ClrType).ToTable(t => t.HasComment(entityDescription));
            }
            // 循环实体属性配置Comment
            IMutableProperty[] mutableProperties = mutableEntityType.GetProperties().ToArray();
            foreach (IMutableProperty mutableProperty in mutableProperties)
            {
                var propertyInfo = mutableProperty.PropertyInfo;
                var propertyType = propertyInfo?.PropertyType;
                if (propertyInfo == null)
                {
                    continue;
                }
                string fieldDescription = propertyInfo.GetDescription();
                fieldDescription ??= "";

                // 如果该列的实体属性是枚举类型，把枚举的说明追加到列说明
                if (propertyType?.IsEnum == true)
                {
                    Type enumType = propertyType;
                    Array values = enumType.GetEnumValues();
                    int[] intValues = values.Cast<int>().ToArray();
                    string[] names = values.Cast<Enum>().Select(m => m.ToDescription()).ToArray();
                    var enumDescriptionList = new List<string>();
                    for (int i = 0; i < intValues.Length; i++)
                    {
                        string value = intValues[i].ToString();
                        string name = names[i];
                        enumDescriptionList.Add($"[{value}]{name}");
                    }
                    var isFlags = enumType.HasAttribute<FlagsAttribute>();
                    var enumTypeDescription = enumType.GetDescription();
                    enumTypeDescription = $"{enumTypeDescription}{(isFlags ? "(标志位枚举)" : string.Empty)}";
                    var enumDescription = $"({(enumTypeDescription.IsMissing() ? "" : $"{enumTypeDescription}：")}{string.Join("；", enumDescriptionList)})";
                    if (!enumDescription.IsMissing())
                    {
                        fieldDescription = $"{fieldDescription}{enumDescription}";
                    }
                }
                // 添加列说明
                if (!fieldDescription.IsMissing())
                {
                    modelBuilder.Entity(mutableEntityType.ClrType).Property(propertyInfo.Name).HasComment(fieldDescription);
                }
            }
        }

    }
}